using System.Globalization;
using System.Text;
using CalcSharp.Core;
using CalcSharp.Core.Containers;

namespace CalcSharp
{
    sealed class Language
    {
        private Language() { }
        public static Tresult ParseIF(string [] param)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 2; i < param.Length; i++)
            {
                sb.Append(param[i]);
                if (i != param.Length-1) sb.Append(" ");
            }
            ReversePolishNotation rp = new ReversePolishNotation();
            rp.Parse(param[1]);
            if (rp.Evaluate() > 0) MiscFuncts.RunBlock(sb.ToString());
            return Program.result;
        }

        public static Tresult ParseFor(string[] param)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 5; i < param.Length; i++)
            {
                sb.Append(param[i]);
                if (i != param.Length - 1) sb.Append(" ");
            }
            if (param[4].ToUpper(CultureInfo.CurrentCulture) != "INC" && param[4].ToUpper(CultureInfo.CurrentCulture) != "DEC") throw new CSException("Invalid direction");
            if (param[4].ToUpper(CultureInfo.CurrentCulture) == "INC")
            {
                if (MiscFuncts.parsestr(param[2]) > MiscFuncts.parsestr(param[3])) throw new CSException("This results in an infinite cycle");
                for (int i = (int)MiscFuncts.parsestr(param[2]); i <= (int)MiscFuncts.parsestr(param[3]); i++)
                {
                    Program.loaded.Mem[param[1]] = i;
                    MiscFuncts.RunBlock(sb.ToString());
                }
            }
            if (param[4].ToUpper(CultureInfo.CurrentCulture) == "DEC")
            {
                if (MiscFuncts.parsestr(param[2]) < MiscFuncts.parsestr(param[3])) throw new CSException("This results in an infinite cycle");
                for (int i = (int)MiscFuncts.parsestr(param[2]); i >= (int)MiscFuncts.parsestr(param[3]); i--)
                {
                    Program.loaded.Mem[param[1]] = i;
                    MiscFuncts.RunBlock(sb.ToString());
                }
            }
            return Program.result;
        }

        public static Tresult ParseCstyleFor(string[] param)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 4; i < param.Length; i++)
            {
                sb.Append(param[i]);
                if (i != param.Length - 1) sb.Append(" ");
            }
            ReversePolishNotation start = new ReversePolishNotation();
            ReversePolishNotation iteration = new ReversePolishNotation();
            ReversePolishNotation limit = new ReversePolishNotation();
            start.Parse(param[1]);
            iteration.Parse(param[3]);
            limit.Parse(param[2]);
            start.Evaluate();
            do
            {
                iteration.Evaluate();
                MiscFuncts.RunBlock(sb.ToString());
            }
            while (limit.Evaluate() == 1);
            return Program.result;
        }

        public static Tresult ParseForeach(string[] param)
        {
            StringBuilder sb = new StringBuilder();
            double item;
            for (int i = 3; i < param.Length; i++)
            {
                sb.Append(param[i]);
                if (i != param.Length - 1) sb.Append(" ");
            }
            for (int i = 0; i < Program.loaded.Set_mem[param[2]].Count; i++)
            {
                item = Program.loaded.Set_mem[param[2]][i];
                Program.loaded.Mem[param[1]] = item;
                MiscFuncts.RunBlock(sb.ToString());
                Program.loaded.Set_mem[param[2]][i] = item;
            }
            return Program.result;
        }
    }
}